package com.mpgame.common.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import com.google.common.net.HostAndPort;
import com.orbitz.consul.Consul;
import com.orbitz.consul.model.health.ServiceHealth;

import io.netty.util.internal.ThreadLocalRandom;

public class ConsulServiceDiscovery {
    private final Consul consul;
    private final Map<String, List<String>> cache = new ConcurrentHashMap<>();
    private final Map<String, Long> lastFetchTime = new ConcurrentHashMap<>();
    private final long ttlMillis;

    public ConsulServiceDiscovery(String host, int port) {
        this(host, port, 10_000);
    }

    public ConsulServiceDiscovery(String host, int port, long ttlMillis) {
        this.consul = Consul.builder().withHostAndPort(HostAndPort.fromParts(host, port)).build();
        this.ttlMillis = ttlMillis;
    }

    public Optional<String> getService(String serviceName){
        long now = System.currentTimeMillis();
        if(needRefresh(serviceName, now)){
            try{
                List<ServiceHealth> list = consul.healthClient().getHealthyServiceInstances(serviceName).getResponse();
                List<String> addresses = new ArrayList<>();
                for(ServiceHealth sh : list){
                    String address = sh.getService().getAddress();
                    if(address == null || address.isEmpty()){
                        address = sh.getNode().getAddress();
                    }
                    Integer port = sh.getService().getPort();
                    if(address != null && port != null && port > 0){
                        addresses.add(address + ":" + port);
                    }
                }
                if(addresses.isEmpty()){
                    Log.warn("Consul 未找到健康实例：" + serviceName);
                    
                }else{
                    cache.put(serviceName, addresses);
                    lastFetchTime.put(serviceName, now);
                    Log.info("Consul 刷新服务：" + serviceName + "->" + addresses);
                }
            }catch(Exception e){
                Log.err("Consul 查询失败：" + serviceName + " - " + e.getMessage());
            }
        }
        List<String> cached = cache.get(serviceName);
        if(cached == null || cached.isEmpty()){
            return Optional.empty();
        }
        return Optional.of(cached.get(ThreadLocalRandom.current().nextInt(cached.size())));
    }

    private boolean needRefresh(String serviceName, long now) {
        return !cache.containsKey(serviceName) || now - lastFetchTime.getOrDefault(serviceName, 0L) > ttlMillis;
    }
}
